package com.yunpuvip.sachet.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.img.Img;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yunpuvip.sachet.biz.entity.BalanceHistory;
import com.yunpuvip.sachet.biz.entity.Player;
import com.yunpuvip.sachet.biz.mapper.PlayerMapper;
import com.yunpuvip.sachet.biz.model.params.BalanceHistoryParam;
import com.yunpuvip.sachet.biz.model.params.PlayerParam;
import com.yunpuvip.sachet.biz.model.result.PlayerResult;
import com.yunpuvip.sachet.biz.service.BalanceHistoryService;
import  com.yunpuvip.sachet.biz.service.PlayerService;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunpuvip.sachet.modular.core.exception.GunsException;
import com.yunpuvip.sachet.modular.core.exception.GunsExceptionEnum;
import com.yunpuvip.sachet.modular.core.exception.RestServiceExceptionEnum;
import com.yunpuvip.sachet.modular.factory.RandomCodeFactory;
import com.yunpuvip.sachet.modular.page.LayuiPageFactory;
import com.yunpuvip.sachet.modular.page.LayuiPageInfo;
import com.yunpuvip.sachet.modular.util.BigDecimalUtil;
import com.yunpuvip.sachet.modular.util.cache.CacheKit;
import com.yunpuvip.sachet.modular.util.sms.SMSTemplateType;
import com.yunpuvip.sachet.modular.util.sms.Sendsms;
import com.yunpuvip.sachet.modular.vo.rest.request.UserMsgVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 会员用户 服务实现类
 * </p>
 *
 * @author wushaohong
 * @since 2019-08-10
 */
@Service
public class PlayerServiceImpl extends ServiceImpl<PlayerMapper, Player> implements PlayerService {
    @Autowired
private BalanceHistoryService balanceHistoryService;
    @Override
    public void add(PlayerParam param){
        Player entity = getEntity(param);
        this.save(entity);
    }
    @Override
    public void delete(PlayerParam param){
        this.removeById(getKey(param));
    }

    @Override
    public void update(PlayerParam param){
        Player oldEntity = getOldEntity(param);
        Player newEntity = getEntity(param);

        //发送短信
        BigDecimal oldBalance = oldEntity.getBalance();
        BigDecimal newBalance = newEntity.getBalance();

        if(oldBalance.compareTo(newBalance)!=0){
            String s = newBalance.setScale(2).toString();
            HashMap<String, String> map = new HashMap<>();
            String nickname = oldEntity.getNickname();
            if(StrUtil.isEmpty(nickname)){
                nickname=oldEntity.getPhone();
            }
            map.put("name",nickname);
            map.put("balance",newBalance.setScale(2).toString());
            String prettyStr = JSONUtil.toJsonPrettyStr(map);
            Sendsms.sendSmsRechargeMsg(oldEntity.getPhone(),prettyStr, SMSTemplateType.UPDATE.getCode());
            //插入余额变动记录
            BalanceHistoryParam balanceHistory = new BalanceHistoryParam();
            BigDecimal subtract=BigDecimal.ZERO;
            subtract = newBalance.subtract(oldBalance);
            if(BigDecimal.ZERO.compareTo(subtract)!=0) {
                balanceHistory.setChangeBalance(subtract.abs());
                balanceHistory.setBalanceBefore(oldBalance);
                balanceHistory.setBalanceAfter(newBalance);
                balanceHistory.setReason("后台修改余额");
                balanceHistory.setPlayerId(oldEntity.getId());
                balanceHistory.setPlayerName(oldEntity.getNickname());
                balanceHistoryService.add(balanceHistory);
            }
        }
        ToolUtil.copyProperties(newEntity, oldEntity);

        this.updateById(newEntity);
    }

    @Override
    public PlayerResult findBySpec(PlayerParam param){
        return null;
    }

    @Override
    public List<PlayerResult> findListBySpec(PlayerParam param){
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(PlayerParam param){
        Page pageContext = getPageContext();
        LambdaQueryWrapper<Player> lambda = new QueryWrapper<Player>().lambda();
        String nickname = param.getNickname();
        String phone = param.getPhone();
        String userNo = param.getUserNo();
        if(StrUtil.isNotBlank(nickname)) {
            lambda.like(Player::getNickname,nickname);
        }if(StrUtil.isNotBlank(phone)) {
            lambda.like(Player::getPhone,phone);
        }if(StrUtil.isNotBlank(userNo)) {
            lambda.like(Player::getUserNo,userNo);
        }
        lambda.orderByDesc(Player::getCreateTime);
        IPage page = this.page(pageContext, lambda);
        return LayuiPageFactory.createPageInfo(page);
    }

    private Serializable getKey(PlayerParam param){
        return param.getId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private Player getOldEntity(PlayerParam param) {
        return this.getById(getKey(param));
    }

    private Player getEntity(PlayerParam param) {
        Player entity = new Player();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

    @Override
    public Player getPlayer(Integer id) {
        return baseMapper.selectById(id);
    }

    @Override
    public Player playerWxLogin(String token, Integer id) {
        return null;
    }

    @Override
    public Player insertOrUpdateUser(String phone, String token, Date expireTime,String name) {
        Player playerByPhone = getPlayerByPhone(phone);

        if(ObjectUtil.isNull(playerByPhone)){
            playerByPhone = new Player();
            playerByPhone.setLoginExpireTime(expireTime);
            playerByPhone.setToken(token);
            playerByPhone.setPhone(phone);
            playerByPhone.setUserhead("/img/default.jpg");
            playerByPhone.setLastLogin(new Date());
            String userNo = getNewUserNo();
            playerByPhone.setNickname(name);
            playerByPhone.setUserNo(userNo);
            playerByPhone.setNewUser(true);
            baseMapper.insert(playerByPhone);
        }else {
            String nickname = playerByPhone.getNickname();
            if (!StrUtil.equals(nickname,name)){
                throw new GunsException(RestServiceExceptionEnum.NAME_ERROR);
            }
            String oldToken = playerByPhone.getToken();
            Date loginExpireTime = playerByPhone.getLoginExpireTime();
            //判断token是否不存在且过时
            if(StrUtil.isBlank(oldToken)||ObjectUtil.isNull(loginExpireTime)||DateUtil.isExpired(new Date(), DateField.HOUR,0,loginExpireTime)){
                System.err.println("未登录获取新token");
                playerByPhone.setToken(token);
                playerByPhone.setLoginExpireTime(expireTime);
            }
            playerByPhone.setLastLogin(new Date());
            baseMapper.updateById(playerByPhone);
        }
        return playerByPhone;
    }
    @Override
    public Player getPlayerByPhone(String phone) {

        LambdaQueryWrapper<Player> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Player::getPhone,phone);
        return baseMapper.selectOne(wrapper);
    }

    @Override
    public String genUserNo() {
        String random = RandomCodeFactory.getRandomNumAndEnglish();
        LambdaQueryWrapper<Player> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Player::getUserNo,random);
        Player player = baseMapper.selectOne(wrapper);
       while(ObjectUtil.isNotNull(player)){
            random = RandomCodeFactory.getRandomNumAndEnglish();
            wrapper.eq(Player::getUserNo,random);
            player = baseMapper.selectOne(wrapper);

        }
        return random;
    }


    @Override
    public boolean userLoginOut(Player player) {
        String token = player.getToken();
        Integer id = player.getId();
        //在清理数据的登录状态
        Player newPlayer = getPlayer(id);
        newPlayer.setLoginExpireTime(DateUtil.parseDateTime("1990-01-01  11:11:11"));
        newPlayer.setToken("");
        baseMapper.updateById(newPlayer);
        return true;
    }

    @Override
    public boolean updateUserMsg(UserMsgVo userMsgVo) {
        Integer id = userMsgVo.getId();
        Player player = getPlayer(id);
        if(ObjectUtil.isNull(player)){
            throw new GunsException(RestServiceExceptionEnum.DATA_NOT_EXIST);
        }
        String address = userMsgVo.getAddress();
        String company = userMsgVo.getCompany();
        String headUrl = userMsgVo.getHeadUrl();
        String nickName = userMsgVo.getNickName();
        if(StrUtil.isNotEmpty(address)){
            player.setAddress(address);
        }
        if(StrUtil.isNotEmpty(company)){
            player.setCompany(company);
        }
        if(StrUtil.isNotEmpty(headUrl)){
            player.setUserhead(headUrl);
        }
        if(StrUtil.isNotEmpty(nickName)){
            player.setNickname(nickName);
        }
        baseMapper.updateById(player);
        return true;
    }

    @Override
    public String uploadSingleImage(String hostPath, MultipartFile picture) {
        String suffix = ToolUtil.getFileSuffix(picture.getOriginalFilename());
        //判断文件后缀，防止被黑0101101110101010110
        String[] imgSuffix = {"gif", "png", "jpg", "jpeg"};
        suffix=suffix.toLowerCase();
        if (!ArrayUtil.contains(imgSuffix, suffix)) {
            throw new ServiceException(GunsExceptionEnum.UPLOAD_ERROR);
        }

        String pictureName = IdUtil.simpleUUID() + "." + ToolUtil.getFileSuffix(picture.getOriginalFilename());

        //文件夹加上日期
        String today = DateUtil.format(new Date(), "yyyyMMdd");
        String fullPath=null;
        try {
            String fileSavePath = hostPath + today + File.separator;

            File file = new File(fileSavePath);

            if (!file.exists()) {
                file.mkdirs();
            }
            fullPath = fileSavePath + pictureName;
            System.out.println("fullPath: " + fullPath);
            picture.transferTo(new File(fullPath));
        } catch (Exception e) {
            throw new ServiceException(GunsExceptionEnum.UPLOAD_ERROR);
        }
        String url="/img/" + today + "/" + pictureName;
        return url;
    }
    @Override
    public String changePhoneNum(Integer id, String phoneNum,String token,Date tokenExpireTime) {
        Player player = getPlayer(id);
        if(ObjectUtil.isNull(player)){
            throw new GunsException(RestServiceExceptionEnum.DATA_NOT_EXIST);
        }
        //判断新号码是否已被绑定
        Player playerByPhone = getPlayerByPhone(phoneNum);
        if(ObjectUtil.isNotNull(playerByPhone)){
            throw new GunsException(RestServiceExceptionEnum.PHONE_REPEAT_BINDING);
        }
        player.setPhone(phoneNum);
        player.setToken(token);
        player.setLoginExpireTime(tokenExpireTime);
        baseMapper.updateById(player);
        return  phoneNum;

    }

    @Override
    public String testEX() {

            throw new GunsException(RestServiceExceptionEnum.DATA_NOT_EXIST);

    }


    @Override
    public boolean isTokenExist(String token ,String phone) {
        Player playerByPhone = getPlayerByPhone(phone);
        System.out.println("data:"+token);
        System.out.println("mime:"+playerByPhone.getToken());
        if(ObjectUtil.isNull(playerByPhone)){
            return false;
        }
        if(!StrUtil.equals(token,playerByPhone.getToken())){
            System.out.println("token 不匹配");
            return false;
        }
        return true;
    }

    @Override
    public String getNewUserNo() {
         String maxUserNo = (String) CacheKit.get("CONSTANT", "userNo");
         if(StrUtil.isEmpty(maxUserNo)){
             //从数据库那最新的用户编号
           //  LambdaQueryWrapper<Object> wrapper = new LambdaQueryWrapper<>();
              maxUserNo = baseMapper.selectMaxUserNo();
             if(StrUtil.isEmpty(maxUserNo)){
              maxUserNo="80001901";
             }
         }
        Long l = Long.valueOf(maxUserNo) + 1;
        maxUserNo=l.toString();
        CacheKit.put("CONSTANT", "userNo",maxUserNo);
        return maxUserNo;
    }

    public static void main(String[] args) {
        boolean expired = DateUtil.isExpired(new Date(), DateField.HOUR, 0, DateUtil.parseDateTime("2019-8-10 10:10:10"));
        System.out.println(DateUtil.parseDateTime("1998-01-01 11:11:11"));
    }
}
